//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.eshop.modules.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.eshop.api.EshopException;
import com.eshop.common.service.impl.BaseServiceImpl;
import com.eshop.common.utils.QueryHelpPlus;
import com.eshop.dozer.service.IGenerator;
import com.eshop.exception.BadRequestException;
import com.eshop.exception.EntityExistException;
import com.eshop.modules.system.domain.Menu;
import com.eshop.modules.system.domain.vo.MenuMetaVo;
import com.eshop.modules.system.domain.vo.MenuVo;
import com.eshop.modules.system.service.MenuService;
import com.eshop.modules.system.service.dto.MenuDto;
import com.eshop.modules.system.service.dto.MenuQueryCriteria;
import com.eshop.modules.system.service.dto.RoleSmallDto;
import com.eshop.modules.system.service.mapper.MenuMapper;
import com.eshop.modules.system.service.mapper.RoleMapper;
import com.eshop.utils.FileUtil;
import com.eshop.utils.StringUtils;
import com.eshop.utils.ValidationUtil;
import com.github.pagehelper.PageInfo;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
@CacheConfig(
        cacheNames = {"menu"}
)
@Transactional(
        propagation = Propagation.SUPPORTS,
        readOnly = true,
        rollbackFor = {Exception.class}
)
public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, Menu> implements MenuService {
    private final IGenerator generator;
    private final MenuMapper menuMapper;
    private final RoleMapper roleMapper;

    @Cacheable
    public Map<String, Object> queryAll(MenuQueryCriteria criteria, Pageable pageable) {
        this.getPage(pageable);
        PageInfo<Menu> page = new PageInfo(this.queryAll(criteria));
        Map<String, Object> map = new LinkedHashMap(2);
        map.put("content", this.generator.convert(page.getList(), MenuDto.class));
        map.put("totalElements", page.getTotal());
        return map;
    }

    @Cacheable
    public List<Menu> queryAll(MenuQueryCriteria criteria) {
        return ((MenuMapper)this.baseMapper).selectList(QueryHelpPlus.getPredicate(Menu.class, criteria));
    }

    public void download(List<MenuDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList();
        Iterator var4 = all.iterator();

        while(var4.hasNext()) {
            MenuDto menu = (MenuDto)var4.next();
            Map<String, Object> map = new LinkedHashMap();
            map.put("是否外链", menu.getIFrame());
            map.put("菜单名称", menu.getName());
            map.put("组件", menu.getComponent());
            map.put("上级菜单ID", menu.getPid());
            map.put("排序", menu.getSort());
            map.put("图标", menu.getIcon());
            map.put("链接地址", menu.getPath());
            map.put("缓存", menu.getCache());
            map.put("是否隐藏", menu.getHidden());
            map.put("组件名称", menu.getComponentName());
            map.put("创建日期", menu.getCreateTime());
            map.put("权限", menu.getPermission());
            map.put("类型", menu.getType());
            list.add(map);
        }

        FileUtil.downloadExcel(list, response);
    }

    public Map<String, Object> buildTree(List<MenuDto> menuDtos) {
        List<MenuDto> trees = new ArrayList();
        Set<Long> ids = new HashSet();
        Iterator var4 = menuDtos.iterator();

        while(var4.hasNext()) {
            MenuDto menuDto = (MenuDto)var4.next();
            if (menuDto.getPid() == 0L) {
                ((List)trees).add(menuDto);
            }

            Iterator var6 = menuDtos.iterator();

            while(var6.hasNext()) {
                MenuDto it = (MenuDto)var6.next();
                if (it.getPid().equals(menuDto.getId())) {
                    if (menuDto.getChildren() == null) {
                        menuDto.setChildren(new ArrayList());
                    }

                    menuDto.getChildren().add(it);
                    ids.add(it.getId());
                }
            }
        }

        Map<String, Object> map = new HashMap(2);
        if (((List)trees).size() == 0) {
            trees = (List)menuDtos.stream().filter((s) -> {
                return !ids.contains(s.getId());
            }).collect(Collectors.toList());
        }

        map.put("content", trees);
        map.put("totalElements", menuDtos.size());
        return map;
    }

    public List<MenuVo> buildMenus(List<MenuDto> menuDtos) {
        List<MenuVo> list = new LinkedList();
        menuDtos.forEach((menuDTO) -> {
            if (menuDTO != null) {
                List<MenuDto> menuDtoList = menuDTO.getChildren();
                MenuVo menuVo = new MenuVo();
                menuVo.setName(ObjectUtil.isNotEmpty(menuDTO.getComponentName()) ? menuDTO.getComponentName() : menuDTO.getName());
                menuVo.setPath(menuDTO.getPid() == 0L ? "/" + menuDTO.getPath() : menuDTO.getPath());
                menuVo.setHidden(menuDTO.getHidden());
                if (!menuDTO.getIFrame()) {
                    if (menuDTO.getPid() == 0L) {
                        menuVo.setComponent(StrUtil.isEmpty(menuDTO.getComponent()) ? "Layout" : menuDTO.getComponent());
                    } else if (!StrUtil.isEmpty(menuDTO.getComponent())) {
                        menuVo.setComponent(menuDTO.getComponent());
                    }
                }

                menuVo.setMeta(new MenuMetaVo(menuDTO.getName(), menuDTO.getIcon(), !menuDTO.getCache()));
                if (menuDtoList != null && menuDtoList.size() != 0) {
                    menuVo.setAlwaysShow(true);
                    menuVo.setRedirect("noredirect");
                    menuVo.setChildren(this.buildMenus(menuDtoList));
                } else if (menuDTO.getPid() == 0L) {
                    MenuVo menuVo1 = new MenuVo();
                    menuVo1.setMeta(menuVo.getMeta());
                    if (!menuDTO.getIFrame()) {
                        menuVo1.setPath("index");
                        menuVo1.setName(menuVo.getName());
                        menuVo1.setComponent(menuVo.getComponent());
                    } else {
                        menuVo1.setPath(menuDTO.getPath());
                    }

                    menuVo.setName((String)null);
                    menuVo.setMeta((MenuMetaVo)null);
                    menuVo.setComponent("Layout");
                    List<MenuVo> list1 = new ArrayList();
                    list1.add(menuVo1);
                    menuVo.setChildren(list1);
                }

                list.add(menuVo);
            }

        });
        return list;
    }

    @Cacheable(
            key = "'tree'"
    )
    public Object getMenuTree(List<Menu> menus) {
        List<Map<String, Object>> list = new LinkedList();
        menus.forEach((menu) -> {
            if (menu != null) {
                List<Menu> menuList = this.menuMapper.findByPid(menu.getId());
                Map<String, Object> map = new HashMap(16);
                map.put("id", menu.getId());
                map.put("label", menu.getName());
                if (menuList != null && menuList.size() != 0) {
                    map.put("children", this.getMenuTree(menuList));
                }

                list.add(map);
            }

        });
        return list;
    }

    public Set<Menu> getDeleteMenus(List<Menu> menuList, Set<Menu> menuSet) {
        Iterator var3 = menuList.iterator();

        while(var3.hasNext()) {
            Menu menu1 = (Menu)var3.next();
            menuSet.add(menu1);
            List<Menu> menus = this.menuMapper.findByPid(menu1.getId());
            if (menus != null && menus.size() != 0) {
                this.getDeleteMenus(menus, menuSet);
            }
        }

        return menuSet;
    }

    @Cacheable(
            key = "'pid:'+#p0"
    )
    public List<Menu> findByPid(long pid) {
        return this.menuMapper.findByPid(pid);
    }

    public List<MenuDto> findByRoles(List<RoleSmallDto> roles) {
        List<Long> roleIds = (List)roles.stream().map((i) -> {
            Long role = i.getId();
            return role;
        }).collect(Collectors.toList());
        List<Menu> list = this.menuMapper.selectListByRoles(roleIds);
        return this.generator.convert(list, MenuDto.class);
    }

    @CacheEvict(
            allEntries = true
    )
    public void delete(Set<Menu> menuSet) {
        Iterator var2 = menuSet.iterator();

        while(var2.hasNext()) {
            Menu menu = (Menu)var2.next();
            this.roleMapper.untiedMenu(menu.getId());
            this.removeById(menu.getId());
        }

    }

    @CacheEvict(
            allEntries = true
    )
    public void update(Menu resources) {
        if (resources.getId().equals(resources.getPid())) {
            throw new BadRequestException("上级不能为自己");
        } else {
            Menu menu = (Menu)this.getById(resources.getId());
            ValidationUtil.isNull(menu.getId(), "Permission", "id", resources.getId());
            this.isExitHttp(resources);
            Menu menu1 = (Menu)this.getOne((Wrappers.<Menu>lambdaQuery()).eq(Menu::getName, resources.getName()));
            if (menu1 != null && !menu1.getId().equals(menu.getId())) {
                throw new EntityExistException(Menu.class, "name", resources.getName());
            } else {
                if (StringUtils.isNotBlank(resources.getComponentName()) && resources.getType() != 0) {
                    int menuCount = ((LambdaQueryChainWrapper)this.lambdaQuery().eq(Menu::getComponentName, resources.getComponentName())).count();
                    if (menuCount > 1) {
                        throw new EshopException("请保持菜单组件名称唯一");
                    }

                    menu1 = (Menu)this.getOne((Wrappers.<Menu>lambdaQuery()).eq(Menu::getComponentName, resources.getComponentName()));
                    if (menu1 != null && !menu1.getId().equals(menu.getId())) {
                        throw new EntityExistException(Menu.class, "componentName", resources.getComponentName());
                    }
                }

                menu.setId(resources.getId());
                menu.setName(resources.getName());
                menu.setComponent(resources.getComponent());
                menu.setPath(resources.getPath());
                menu.setIcon(resources.getIcon());
                menu.setIFrame(resources.getIFrame());
                menu.setPid(resources.getPid());
                menu.setSort(resources.getSort());
                menu.setCache(resources.getCache());
                menu.setHidden(resources.getHidden());
                menu.setComponentName(resources.getComponentName());
                menu.setPermission(resources.getPermission());
                menu.setType(resources.getType());
                this.saveOrUpdate(menu);
            }
        }
    }

    @CacheEvict(
            allEntries = true
    )
    public MenuDto create(Menu resources) {
        this.isExitHttp(resources);
        if (this.getOne((Wrappers.<Menu>lambdaQuery().eq(Menu::getName, resources.getName()))) != null) {
            throw new EntityExistException(Menu.class, "name", resources.getName());
        } else if (StringUtils.isNotBlank(resources.getComponentName()) && this.getOne((Wrappers.<Menu>lambdaQuery()).eq(Menu::getComponentName, resources.getComponentName())) != null) {
            throw new EntityExistException(Menu.class, "componentName", resources.getComponentName());
        } else {
            this.save(resources);
            return (MenuDto)this.generator.convert(resources, MenuDto.class);
        }
    }

    private void isExitHttp(Menu resources) {
        if (resources.getIFrame()) {
            String http = "http://";
            String https = "https://";
            if (!resources.getPath().toLowerCase().startsWith(http) && !resources.getPath().toLowerCase().startsWith(https)) {
                throw new BadRequestException("外链必须以http://或者https://开头");
            }
        }

    }

    public MenuServiceImpl(final IGenerator generator, final MenuMapper menuMapper, final RoleMapper roleMapper) {
        this.generator = generator;
        this.menuMapper = menuMapper;
        this.roleMapper = roleMapper;
    }
}
